package com.spark.modules.generation.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.spark.common.core.Result;
import com.spark.common.core.entity.generation.GenModel;
import com.spark.common.core.entity.generation.GenModelFields;
import com.spark.common.exception.SparkException;
import com.spark.common.utils.JsonUtils;
import com.spark.modules.generation.entity.GenConfig;
import com.spark.modules.generation.entity.GenDefaultFields;
import com.spark.modules.generation.entity.GenDesignPage;
import com.spark.modules.generation.entity.GenFieldMapping;
import com.spark.modules.generation.entity.model.TemplateModel;
import com.spark.modules.generation.entity.vo.GenModelFieldsVo;
import com.spark.modules.generation.mapper.*;
import com.spark.modules.generation.service.IGenCodeService;
import com.spark.modules.utils.CodeGeneratorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 代码生成Service
 *
 * @author LYCHEE
 * @date 2025/3/5 12:41
 */
@Service
public class GenCodeServiceImpl implements IGenCodeService {

    @Resource
    private GenModelMapper genModelMapper;
    @Resource
    private GenModelFieldsMapper genModelFieldsMapper;
    @Resource
    private GenConfigMapper genConfigMapper;
    @Resource
    private GenFieldMappingMapper genFieldMappingMapper;
    @Resource
    private GenDefaultFieldsMapper genDefaultFieldsMapper;
    @Resource
    private GenDesignPageMapper genDesignPageMapper;
    @Resource
    private IdentifierGenerator identifierGenerator;

    public static final String PATH = "/src/main/java/";

    /**
     * 预览代码
     *
     * @param modelCode 模型编码
     * @return 数据
     */
    @Override
    public List<Map<String, String>> previewCode(String modelCode) {
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();
        Map<String, Object> templateParams = this.getTemplateParams(modelCode);
        Map<String, TemplateModel> template = this.getBankEndTemplate(modelCode);
        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        for (Map.Entry<String, TemplateModel> entry : template.entrySet()) {
            String key = entry.getKey();
            TemplateModel value = entry.getValue();
            codeGen.setTemplateLoaderPath(value.getTemplatePath());
            // 生成预览代码
            String previewCode = codeGen.previewCode(templateParams, key);
            Map<String, String> map = new HashMap<>();
            map.put("key", key.split("\\.")[0]);
            map.put("content", previewCode);
            result.add(map);
        }
        return result;
    }

    /**
     * 生成后端代码到项目
     *
     * @param modelCode 模型编码
     * @return 数据
     */
    @Override
    public Result<?> genCodeToProject(String modelCode) {
        Map<String, Object> templateParams = this.getTemplateParams(modelCode);
        Map<String, TemplateModel> template = this.getBankEndTemplate(modelCode);
        String configStr = (String) templateParams.get("config");
        GenConfig genConfig = JSON.parseObject(configStr, GenConfig.class);
        // 生成路径
        String path = genConfig.getModuleName().concat(PATH).concat(((String) templateParams.get("packageName")).replaceAll("\\.", "/"));
        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        for (Map.Entry<String, TemplateModel> entry : template.entrySet()) {
            String key = entry.getKey();
            TemplateModel value = entry.getValue();
            codeGen.setTemplateLoaderPath(value.getTemplatePath());
            String genPath = path.concat(value.getTargetPath()).concat("/");
            if (StringUtils.isNotEmpty(value.getPrefix())){
                genPath = genPath.concat(value.getPrefix());
            }
            genPath = genPath.concat((String) templateParams.get("ClassName")).concat(value.getSuffix());
            // 生成文件
            codeGen.generateFile(
                    key,
                    genPath,
                    templateParams
                    );
        }
        return Result.ok("代码文件已生成：路径 ===> " + path);
    }

    /**
     * 通过页面ID预览前端代码
     *
     * @param pageId 页面ID
     * @return 代码
     */
    @Override
    public Result<?> previewFrontEndCode(String pageId) {
        GenDesignPage genDesignPage = genDesignPageMapper.selectById(pageId);
        if (Objects.isNull(genDesignPage)) {
            return Result.fail("页面设计出错");
        }
        if (StringUtils.isEmpty(genDesignPage.getPageParams())){
            return Result.fail("保存设计后预览代码");
        }
        // 页面参数
        Map<String, Object> jsonMap = JsonUtils.toMap(genDesignPage.getPageParams());
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();
        Map<String, Object> templateParams = this.getTemplateParams(genDesignPage.getMainModel());
        Map<String, TemplateModel> template = this.getFrontEndTemplate(genDesignPage, "");
        String configStr = (String) templateParams.get("config");
        GenConfig genConfig = JSON.parseObject(configStr, GenConfig.class);
        if (StringUtils.isEmpty(genConfig.getFrontEndPath())) {
            return Result.fail("请先配置前端生成目录");
        }
        // 设置特殊属性,需要设置查询字段下划线转驼峰
        if ("colTable".equals(genDesignPage.getLayout())){
            JSONObject json = JSONObject.parseObject(genDesignPage.getPageParams());
            JSONObject colModel = json.getJSONObject("colModel");
            String mainModelField = colModel.getString("mainModelField");
            if (StringUtils.isNotEmpty(mainModelField)) {
                String strToCamel = com.spark.common.utils.StringUtils.underscoreToCamel(mainModelField);
                templateParams.put("mainModelField", strToCamel);
            }
        }
        templateParams.put("frontEndPath", genConfig.getFrontEndPath());
        templateParams.put("delParams", "${id}");
        templateParams.put("delBatchParams", "${ids}");
        // 表单中状态参数
        templateParams.put("handleFormStatus", "${record.value.id ? '编辑' : '新增'}");
        templateParams.put("pageParams", jsonMap);
        templateParams.put("colTypeSearch", "${typeSearchContent.value}");
        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        for (Map.Entry<String, TemplateModel> entry : template.entrySet()) {
            String key = entry.getKey();
            TemplateModel value = entry.getValue();
            codeGen.setTemplateLoaderPath(value.getTemplatePath());
            // 生成预览代码
            String previewCode = codeGen.previewCode(templateParams, key);
            Map<String, String> map = new HashMap<>();
            map.put("key", key.split("\\.")[0]);
            map.put("content", previewCode);
            result.add(map);
        }
        return Result.ok(result);
    }

    /**
     * 生成前端代码到项目
     *
     * @param pageId 页面ID
     * @return 数据
     */
    @Override
    public Result<?> genCodeFrontEndToProject(String pageId) {
        GenDesignPage genDesignPage = genDesignPageMapper.selectById(pageId);
        if (Objects.isNull(genDesignPage)) {
            return Result.fail("页面设计出错");
        }
        if (StringUtils.isEmpty(genDesignPage.getPageParams())){
            return Result.fail("保存设计后预览代码");
        }
        // 页面参数
        Map<String, Object> jsonMap = JsonUtils.toMap(genDesignPage.getPageParams());
        Map<String, Object> templateParams = this.getTemplateParams(genDesignPage.getMainModel());
        String configStr = (String) templateParams.get("config");
        GenConfig genConfig = JSON.parseObject(configStr, GenConfig.class);
        if (StringUtils.isEmpty(genConfig.getFrontEndPath()) || StringUtils.isEmpty(genConfig.getFrontProjectPath())) {
            return Result.fail("请先配置前端生成目录");
        }
        Map<String, TemplateModel> template = this.getFrontEndTemplate(genDesignPage, genConfig.getFrontEndPath());
        templateParams.put("frontEndPath", genConfig.getFrontEndPath());
        templateParams.put("delParams", "${id}");
        templateParams.put("delBatchParams", "${ids}");
        // 表单中状态参数
        templateParams.put("handleFormStatus", "${record.value.id ? '编辑' : '新增'}");
        templateParams.put("pageParams", jsonMap);
        templateParams.put("colTypeSearch", "${typeSearchContent.value}");
        // 生成路径
        String path = genConfig.getFrontProjectPath();
        if (!genConfig.getFrontProjectPath().endsWith("\\")) {
            path += "/";
        }
        path += "apps/web-antd/src";
        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        for (Map.Entry<String, TemplateModel> entry : template.entrySet()) {
            String key = entry.getKey();
            TemplateModel value = entry.getValue();
            codeGen.setTemplateLoaderPath(value.getTemplatePath());
            String genPath = path.concat(value.getTargetPath()).concat("/");
            if (StringUtils.isNotEmpty(value.getPrefix())){
                genPath = genPath.concat(value.getPrefix());
            }
            if (value.getSuffix().contains(".vue")) {
                genPath = genPath.concat((String) templateParams.get("ClassName")).concat(value.getSuffix());
            } else {
                genPath = genPath.concat((String) templateParams.get("className")).concat(value.getSuffix());
            }
            // 生成文件
            codeGen.generateFile(
                    key,
                    genPath,
                    templateParams
            );
        }
        return Result.ok("生成成功");
    }

    /**
     * 生成菜单SQL
     *
     * @param pageId 页面ID
     * @return 数据
     */
    @Override
    public Result<?> genSql(String pageId) {
        GenDesignPage genDesignPage = genDesignPageMapper.selectById(pageId);
        if (Objects.isNull(genDesignPage)) {
            return Result.fail("页面设计出错");
        }
        // SQL参数
        Map<String, Object> sqlParams = new HashMap<>();
        // 查询生成配置
        GenConfig config = this.getGenConfig();
        if (Objects.isNull(config)) {
            return Result.fail("请配置前端生成目录");
        } else if (StringUtils.isEmpty(config.getFrontEndPath())) {
            return Result.fail("请配置前端生成目录");
        }
        // 获取转换后的模型名称
        String modeName = com.spark.common.utils.StringUtils.underscoreToCamel(genDesignPage.getMainModel());
        String modeNameToUp = com.spark.common.utils.StringUtils.capitalizeFirstLetter(modeName);
        // 生成菜单主键
        sqlParams.put("menuId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("pid", 0);
        if (StringUtils.isNotEmpty(genDesignPage.getParentMenuId())) {
            sqlParams.put("pid", genDesignPage.getParentMenuId());
        }
        sqlParams.put("type", 1);
        sqlParams.put("name", genDesignPage.getMenuName());
        // 路由地址：/前端前缀/模型名称
        sqlParams.put("route_path", "/".concat(config.getFrontEndPath()).concat("/").concat(modeName));
        // 组件路径：前端前缀/模型名称/${模型名称}List
        sqlParams.put("component_path", config.getFrontEndPath().concat("/").concat(modeName).concat("/").concat(modeNameToUp).concat("List"));
        sqlParams.put("perm", config.getModelNamePrefix().concat(":").concat(modeName));
        sqlParams.put("addId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("editId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("delId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("batchDelId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("queryId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("moreId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("detailsId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("childId", String.valueOf(identifierGenerator.nextId(null)));
        sqlParams.put("isAuth", genDesignPage.getIsAuth());
        if (genDesignPage.getIsAuth() == 0 && StringUtils.isNotEmpty(genDesignPage.getAuths())) {
            sqlParams.put("auths", genDesignPage.getAuths());
            // 生成授权菜单SQLID
            sqlParams.put("authMenuId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authAddId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authAddChildId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authEditId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authDelId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authBatchDelId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authQueryById", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authMoreId", String.valueOf(identifierGenerator.nextId(null)));
            sqlParams.put("authDetailsId", String.valueOf(identifierGenerator.nextId(null)));
        }
        sqlParams.put("layout", genDesignPage.getLayout());

        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        codeGen.setTemplateLoaderPath("/sql");
        // 生成预览代码
        String previewCode = codeGen.previewCode(sqlParams, "sql.ftl");
        return Result.ok(previewCode);
    }

    /**
     * 下载后端代码
     *
     * @param response 响应
     * @throws IOException
     */
    @Override
    public void downloadBankCode(String modelCode, HttpServletResponse response) throws IOException {
        Map<String, Object> templateParams = this.getTemplateParams(modelCode);
        Map<String, TemplateModel> template = this.getBankEndTemplate(modelCode);
        // 生成路径
        String path = "src/main/java/".concat(((String) templateParams.get("packageName")).replaceAll("\\.", "/"));
        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        codeGen.generateZip(response.getOutputStream(), template, templateParams, path);
    }
    /**
     * 下载前端代码
     *
     * @param pageId   页面ID
     * @param response 响应
     * @throws IOException
     */
    @Override
    public void downloadFrontCode(String pageId, HttpServletResponse response) throws IOException {
        GenDesignPage genDesignPage = genDesignPageMapper.selectById(pageId);
        if (Objects.isNull(genDesignPage)) {
            throw new SparkException("页面设计出错");
        }
        if (StringUtils.isEmpty(genDesignPage.getPageParams())){
            throw new SparkException("保存设计后下载代码");
        }
        // 页面参数
        Map<String, Object> jsonMap = JsonUtils.toMap(genDesignPage.getPageParams());
        Map<String, Object> templateParams = this.getTemplateParams(genDesignPage.getMainModel());
        String configStr = (String) templateParams.get("config");
        GenConfig genConfig = JSON.parseObject(configStr, GenConfig.class);
        if (StringUtils.isEmpty(genConfig.getFrontEndPath()) || StringUtils.isEmpty(genConfig.getFrontProjectPath())) {
            throw new SparkException("请先配置前端生成目录");
        }
        Map<String, TemplateModel> template = this.getFrontEndTemplate(genDesignPage, genConfig.getFrontEndPath());
        templateParams.put("frontEndPath", genConfig.getFrontEndPath());
        templateParams.put("delParams", "${id}");
        templateParams.put("delBatchParams", "${ids}");
        // 表单中状态参数
        templateParams.put("handleFormStatus", "${record.value.id ? '编辑' : '新增'}");
        templateParams.put("pageParams", jsonMap);
        templateParams.put("colTypeSearch", "${typeSearchContent.value}");
        // 生成路径
        String path = "apps/web-antd/src";
        // 创建代码生成工具
        CodeGeneratorUtils codeGen = new CodeGeneratorUtils();
        codeGen.generateZip(response.getOutputStream(), template, templateParams, path);
    }

    /**
     * 根据模型获取对应的前端模板路径
     *
     * @param designPage 页面
     * @param modelNamePrefix 前端文件夹名称
     * @return 模板数据
     */
    private Map<String, TemplateModel> getFrontEndTemplate(GenDesignPage designPage, String modelNamePrefix) {
        String mainMode = com.spark.common.utils.StringUtils.underscoreToCamel(designPage.getMainModel());
        Map<String, TemplateModel> template = new LinkedHashMap<>();
        String dataTsPath = "/views/" + modelNamePrefix + "/" + mainMode;
        template.put("data.ts.ftl", new TemplateModel("/vue/table", dataTsPath , ".data.ts"));
        // 判断布局
        if("table".equals(designPage.getLayout())){
            template.put("api.ts.ftl", new TemplateModel("/vue/table/api", "/api/" + modelNamePrefix, ".ts"));
            template.put("Table.ftl", new TemplateModel( "/vue/table/table", dataTsPath, "List.vue"));
        } else if ("treeTable".equals(designPage.getLayout())) {
            template.put("treeApi.ts.ftl", new TemplateModel("/vue/table/api", "/api/" + modelNamePrefix, ".ts"));
            template.put("TreeTable.ftl", new TemplateModel( "/vue/table/treeTable", dataTsPath, "List.vue"));
        } else if ("colTable".equals(designPage.getLayout())){
            template.put("api.ts.ftl", new TemplateModel("/vue/table/api", "/api/" + modelNamePrefix, ".ts"));
            template.put("ColTable.ftl", new TemplateModel( "/vue/table/colTable", dataTsPath, "List.vue"));
        }
        // 判断表单类型
        if(StringUtils.isNotEmpty(designPage.getPageParams())) {
            JSONObject json = JSONObject.parseObject(designPage.getPageParams());
            JSONObject formConfig = json.getJSONObject("form");
            JSONObject baseConfig = formConfig.getJSONObject("extra");
            String openFormType = baseConfig.getString("openFormType");
            if ("modal".equals(openFormType)){
                template.put("FormModal.ftl", new TemplateModel( "/vue/table/modules", dataTsPath + "/modules", "FormModal.vue"));
            }else {
                template.put("FormDrawer.ftl", new TemplateModel( "/vue/table/modules", dataTsPath + "/modules", "FormDrawer.vue"));
            }
        }
        return template;
    }


    /**
     * 根据模型获取对应的后端模板路径
     *
     * @param modelCode 模板编码
     * @return 模板数据
     */
    private Map<String, TemplateModel> getBankEndTemplate(String modelCode) {
        Map<String, TemplateModel> template = new LinkedHashMap<>();
        template.put("controller.ftl", new TemplateModel("/controller", "/controller", "Controller.java"));
        template.put("entity.ftl", new TemplateModel("/entity", "/entity", ".java"));
        template.put("IService.ftl", new TemplateModel( "/service", "/service", "Service.java", "I"));
        template.put("ServiceImpl.ftl", new TemplateModel( "/service", "/service/impl", "ServiceImpl.java"));
        template.put("Mapper.ftl", new TemplateModel("/mapper", "/mapper", "Mapper.java"));
        template.put("MapperXml.ftl", new TemplateModel("/mapper", "/mapper/xml", "Mapper.xml"));
        return template;
    }

    /**
     * 获取模板参数
     *
     * @param modelCode 模型code
     * @return 模板参数
     */
    private Map<String, Object> getTemplateParams(String modelCode) {
        GenModel genModel = this.getModel(modelCode);
        List<GenModelFields> modelFields = this.getModelFields(genModel);
        GenConfig genConfig = this.getGenConfig();
        List<GenFieldMapping> fieldMappings = this.getFieldMappings();
        List<GenDefaultFields> defaultFields = this.getDefaultFields(genModel.getModelCharacter());
        return this.combinationTemplateParams(genModel, modelFields, genConfig, fieldMappings, defaultFields);
    }

    /**
     * 组合模板数据
     *
     * @param genModel      模型
     * @param modelFields   模型字段
     * @param genConfig     生成配置
     * @param fieldMappings 字段映射
     * @param defaultFields 默认字段
     * @return 组合数据
     */
    private Map<String, Object> combinationTemplateParams(GenModel genModel, List<GenModelFields> modelFields
            , GenConfig genConfig, List<GenFieldMapping> fieldMappings, List<GenDefaultFields> defaultFields) {
        List<String> defaultFieldsList = defaultFields.stream().map(GenDefaultFields::getFieldName).collect(Collectors.toList());
        Map<String, Object> params = new HashMap<>();
        params.put("authorName", StringUtils.isEmpty(genConfig.getAuthorName()) ? "LYCHEE" : genConfig.getAuthorName());
        params.put("packageName", genConfig.getPackageName());
        params.put("modulePath", genConfig.getModelNamePrefix());
        params.put("dateTime", DateUtils.format(new Date(), "yyyy/MM/dd HH:mm"));
        params.put("tableName", genModel.getModelCode());
        params.put("functionName", genModel.getModelName());
        String className = com.spark.common.utils.StringUtils.underscoreToCamel(genModel.getModelCode());
        params.put("businessPath", genModel.getBusinessPath());
        params.put("ClassName", Character.toUpperCase(className.charAt(0)) + className.substring(1));
        params.put("className", className);
        params.put("model", genModel.getModelCharacter());
        params.put("config", JSON.toJSONString(genConfig));
        // 设置权限字符前缀：模块名称:模型名称:标识
        String prem = genConfig.getModelNamePrefix().concat(":").concat(className);
        params.put("prem", prem);
        List<GenModelFieldsVo> fields = new ArrayList<>();
        for (GenModelFields modelField : modelFields) {
            if (defaultFieldsList.contains(modelField.getFieldName())) {
                continue;
            }
            // 下划线转驼峰
            modelField.setFieldName(com.spark.common.utils.StringUtils.underscoreToCamel(modelField.getFieldName()));
            GenModelFieldsVo modelFieldvo = new GenModelFieldsVo(modelField);
            for (GenFieldMapping fieldMapping : fieldMappings) {
                if (modelFieldvo.getFieldType().equals(fieldMapping.getFieldType())) {
                    modelFieldvo.setFieldPackagePath(fieldMapping.getJavaFieldPackage());
                    fields.add(modelFieldvo);
                    break;
                }
            }
        }
        params.put("fields", fields);
        return params;
    }

    /**
     * 获取默认字段
     *
     * @param modelCharacter 模型特性 单表single 树表tree
     * @return
     */
    private List<GenDefaultFields> getDefaultFields(String modelCharacter) {
        LambdaQueryWrapper<GenDefaultFields> defaultFieldsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        defaultFieldsLambdaQueryWrapper.eq(GenDefaultFields::getIsCommon, 0);
        if ("tree".equals(modelCharacter)) {
            defaultFieldsLambdaQueryWrapper.or().eq(GenDefaultFields::getIsCommon, 1).eq(GenDefaultFields::getTableType, "tree");
        }
        defaultFieldsLambdaQueryWrapper.orderByAsc(GenDefaultFields::getCreateTime);
        List<GenDefaultFields> defaultFields = genDefaultFieldsMapper.selectList(defaultFieldsLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(defaultFields)) {
            throw new RuntimeException("请配置默认字段");
        }
        return defaultFields;
    }

    /**
     * 字段映射规则
     *
     * @return 字段映射规则
     */
    private List<GenFieldMapping> getFieldMappings() {
        LambdaQueryWrapper<GenFieldMapping> fieldMappingLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fieldMappingLambdaQueryWrapper.eq(GenFieldMapping::getStatus, 0);
        List<GenFieldMapping> fieldMappings = genFieldMappingMapper.selectList(fieldMappingLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(fieldMappings)) {
            throw new RuntimeException("请配置字段映射规则");
        }
        return fieldMappings;
    }

    /**
     * 生成配置信息
     *
     * @return 配置信息
     */
    private GenConfig getGenConfig() {
        List<GenConfig> genConfigs = genConfigMapper.selectList(new QueryWrapper<>());
        if (!CollectionUtils.isEmpty(genConfigs)) {
            return genConfigs.get(0);
        }
        throw new SparkException("请配置生成信息");
    }

    /**
     * 通过模型获取模型字段信息
     *
     * @param model 模型信息
     * @return 模型字段
     */
    private List<GenModelFields> getModelFields(GenModel model) {
        LambdaQueryWrapper<GenModelFields> modelFieldsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        modelFieldsLambdaQueryWrapper.eq(GenModelFields::getModelId, model.getId()).orderByAsc(GenModelFields::getCreateTime);;
        List<GenModelFields> modelFields = genModelFieldsMapper.selectList(modelFieldsLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(modelFields)) {
            throw new SparkException("模型字段不存在");
        }
        return modelFields;
    }

    /**
     * 获取模型信息
     *
     * @param modelCode 模型编码
     * @return 模型
     */
    private GenModel getModel(String modelCode) {
        LambdaQueryWrapper<GenModel> modelLambdaQueryWrapper = new LambdaQueryWrapper<>();
        modelLambdaQueryWrapper.eq(GenModel::getModelCode, modelCode);
        GenModel genModel = genModelMapper.selectOne(modelLambdaQueryWrapper);
        if (Objects.isNull(genModel)) {
            throw new SparkException("模型数据不存在");
        }
        if (1 == genModel.getModelSyncStatus()) {
            throw new SparkException("请先同步数据库");
        }
        return genModel;
    }
}
